#include "MainWindow.h"
#include "ui_MainWindow.h"
#include "QDebug"
#include "CircuitGraph.h"
#include "Gate.h"
#include "ANDGate.h"
#include "ORGate.h"
#include "NOTGate.h"
#include "XORGate.h"
#include "XNORGate.h"
#include "NORGate.h"
#include "NANDGate.h"
#include "QMouseEvent"
#include "QFile"
MainWindow::MainWindow(QWidget *parent)//
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->setFixedSize(1080,600);
    //采用邻接表存储电路图，使用vector动态添加门
    circuit= new CircuitGraph();
    //input工具栏连接lambda表达式槽函数
    connect(ui->actionInput,&QAction::triggered,this,[=]()mutable{
        VNode tempnode=VNode();
        Gate* tempgate=new Input();
        tempnode.gate=tempgate;
        tempnode.first=NULL;
        circuit->gates.push_back(tempnode);
        circuit->inputs.push_back(tempgate);
    });
    connect(ui->actionRUN,&QAction::triggered,this,[=]()mutable{
        QVector<int> store;
        //在进行真值表的计算前先将原输入放入vector中存储，在拓扑赋值前取出
        for(int i=0;i<circuit->inputs.length();i++)
            store.push_back(circuit->inputs[i]->output);
        //开始真值表的计算
        int num = (int)pow(2.0, circuit->inputs.length());
        zhenzhibiao.resize(0);
        QString line1="";
        for(int i=0;i<circuit->inputs.length();i++)
        {
            line1.append(circuit->inputs[i]->gateName);
            line1.append(" ");
        }
        for(int i=circuit->outputs.length()-1;i>=0;i--)
        {
            line1.append(circuit->outputs[i]->gateName);
            line1.append(" ");
        }
        zhenzhibiao.push_back(line1);
        qDebug()<<line1;
        for(int i=1;i<num+1;i++)
        {
            QString templine;
            zhenzhibiao.push_back(templine);
            int temp=i-1;
            for(int j=circuit->inputs.length()-1;j>=0;j--)
            {
                circuit->inputs[j]->output=temp%2;
                QString tempstring=QString::number(temp%2, 10);
                QString tempp=zhenzhibiao[i];
                zhenzhibiao[i]=tempstring;
                zhenzhibiao[i].append(" ");
                zhenzhibiao[i].append(tempp);
                temp/=2;
            }
            QString tempzhenzhi=this->circuit->zhenzhibiao();
            zhenzhibiao[i].append(tempzhenzhi);
            zhenzhibiao[i].append(" ");
        }
        for(int i=0;i<zhenzhibiao.length();i++)
            qDebug()<<zhenzhibiao[i];
        //结束了真值表的计算，将store中的值取出，然后拓扑赋值
         for(int i=0;i<circuit->inputs.length();i++)
             circuit->inputs[i]->output=store[i];
        this->circuit->topology();
    });
    //output工具栏连接lambda表达式槽函数
    connect(ui->actionOutput,&QAction::triggered,this,[=]()mutable{
        VNode tempnode=VNode();
        Gate* tempgate=new Output();
        tempnode.gate=tempgate;
        tempnode.first=NULL;
        circuit->gates.push_back(tempnode);
        circuit->outputs.push_back(tempgate);
        qDebug()<<"输出创建成功";
    });
    connect(ui->actionAND,&QAction::triggered,this,[=]()mutable{
    VNode tempnode=VNode();
    Gate* tempgate=new ANDGate();
    tempnode.gate=tempgate;
    tempnode.first=NULL;
    circuit->gates.push_back(tempnode);
    qDebug()<<"与门创建成功";
    });
    connect(ui->actionOR,&QAction::triggered,this,[=]()mutable{
    VNode tempnode=VNode();
    Gate* tempgate=new ORGate();
    tempnode.gate=tempgate;
    tempnode.first=NULL;
    circuit->gates.push_back(tempnode);
    qDebug()<<"或门创建成功";
    });
    //NOTGate连接槽函数
    connect(ui->actionNOT,&QAction::triggered,this,[=]()mutable{
        VNode tempnode=VNode();
        Gate* tempgate=new NOTGate();
        tempnode.gate=tempgate;
        tempnode.first=NULL;
        circuit->gates.push_back(tempnode);
        qDebug()<<"非门创建成功";
    });
    //XORGate连接槽函数
    connect(ui->actionXOR,&QAction::triggered,this,[=]()mutable{
        VNode tempnode=VNode();
        Gate* tempgate=new XORGate();
        tempnode.gate=tempgate;
        tempnode.first=NULL;
        circuit->gates.push_back(tempnode);
    });
    //XNORGate连接槽函数
    connect(ui->actionXNOR,&QAction::triggered,this,[=]()mutable{
        VNode tempnode=VNode();
        Gate* tempgate=new XNORGate();
        tempnode.gate=tempgate;
        tempnode.first=NULL;
        circuit->gates.push_back(tempnode);
    });
    //NORGate连接槽函数
    connect(ui->actionNOR,&QAction::triggered,this,[=]()mutable{
        VNode tempnode=VNode();
        Gate* tempgate=new NORGate();
        tempnode.gate=tempgate;
        tempnode.first=NULL;
        circuit->gates.push_back(tempnode);
    });
    //NANDGate连接槽函数
    connect(ui->actionNAND,&QAction::triggered,this,[=]()mutable{
        VNode tempnode=VNode();
        Gate* tempgate=new NANDGate();
        tempnode.gate=tempgate;
        tempnode.first=NULL;
        circuit->gates.push_back(tempnode);
    });
    //鼠标点击CLear则清空当前页面
    connect(ui->actionClear,&QAction::triggered,this,[=]()mutable{
        Gate::ASCII=65;
       circuit->gates.resize(0);
       circuit->inputs.resize(0);
       circuit->outputs.resize(0);
        zhenzhibiao.resize(0);
    });
}

void MainWindow::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    drawGate(&painter,circuit->gates);
    DrawTempLine(&painter);
}

void MainWindow::DrawTempLine(QPainter *painter)//鼠标按下并拖拽画线
{
    if(tempLineFlag==1)
    {
        painter->drawLine(temppoint_01.x(),temppoint_01.y(),temppoint_02.x(),temppoint_02.y());
    }
    this->update();
}
void MainWindow::drawGate(QPainter *painter, QVector <VNode> gates)//
{
    for(int i=circuit->gates.length()-1;i>=0;i--)//逆序画门
    {
        for(int j=0;j<circuit->gates[i].gate->curlen;j++)//画连线
        {
                painter->setPen(Qt::blue);
                int to=circuit->gates[i].gate->from[j];
                int x1=circuit->gates[to].gate->gate_x;
                int y1=circuit->gates[to].gate->gate_y;
                int x2=circuit->gates[i].gate->gate_x;
                int y2=circuit->gates[i].gate->gate_y;
                painter->drawLine(x1+50,y1+25,x1+60,y1+25);
                painter->setBrush(QBrush(Qt::SolidPattern));//毛刷：颜色，实图案
                painter->drawEllipse(x1+59,y1+24,3,3);
                painter->setBrush(QBrush(Qt::NoBrush));//毛刷
                if(x2-x1>=50)//to在from的右边
                {
                   painter->drawLine(x1+60,y1+25,x1+60,y2+25);
                   painter->drawLine(x1+60,y2+25,x2,y2+25);
                }
                else if(y1>y2) //to在from左上边
                {
                    painter->drawLine(x1+60,y1+25,x1+60,y2-10);
                    painter->drawLine(x1+60,y2-10,x2-10,y2-10);
                    painter->drawLine(x2-10,y2-10,x2-10,y2+25);
                    painter->drawLine(x2-10,y2+25,x2,y2+25);
                }
                else //to在from左下边
                {
                    painter->drawLine(x1+60,y1+25,x1+60,y2+60);
                    painter->drawLine(x1+60,y2+60,x2-10,y2+60);
                    painter->drawLine(x2-10,y2+60,x2-10,y2+25);
                    painter->drawLine(x2-10,y2+25,x2,y2+25);
                }
        }
        if(circuit->gates[i].gate->clickState==2)
        {
            painter->setPen(Qt::red);
        }
        else
        {
            painter->setPen(Qt::blue);
        }
        painter->drawRect(circuit->gates[i].gate->gate_x,circuit->gates[i].gate->gate_y,50,50);
        QRect r,x;
        QString tempstirng=circuit->gates[i].gate->gateType;
        if(circuit->gates[i].gate->type==0)
        {
            painter->drawText(circuit->gates[i].gate->gate_x+2, circuit->gates[i].gate->gate_y+20, 120, 20, 0, tempstirng, &r);
        }
        else if(circuit->gates[i].gate->type==1)
        {
            tempstirng =tempstirng.append( QString::number(circuit->gates[i].gate->output));
            painter->drawText(circuit->gates[i].gate->gate_x+2, circuit->gates[i].gate->gate_y+20, 120, 20, 0, tempstirng, &r);
        }
        else if(circuit->gates[i].gate->type==2)
        {
            if(circuit->gates[i].gate->output!=233)
                tempstirng =tempstirng.append( QString::number(circuit->gates[i].gate->output));

            painter->drawText(circuit->gates[i].gate->gate_x+2, circuit->gates[i].gate->gate_y+20, 120, 20, 0, tempstirng, &r);
        }
        if(circuit->gates[i].gate->type==3)
        {
            painter->drawText(circuit->gates[i].gate->gate_x+2, circuit->gates[i].gate->gate_y+20, 120, 20, 0, tempstirng, &r);
            painter->drawEllipse(circuit->gates[i].gate->gate_x+50,circuit->gates[i].gate->gate_y+23,5,5);
        }
      painter->drawText(800, 180, 120, 20, 0, "真值表：", &x);
      for(int i=0;i<zhenzhibiao.length();i++)
      {
          painter->drawText(800, 200+20*i, 120, 20, 0, zhenzhibiao[i], &x);
      }
        this->update();//刷新
    }
}

void MainWindow::mousePressEvent(QMouseEvent *e)
{
    QPoint point = e->pos();
    temppoint_01=e->pos();
    temppoint_02=temppoint_01;
    tempLineFlag= circuit->selectGate_1(point.x(),point.y())/*| this->select_Input_Output_1(point.x(),point.y())*/;
}
void MainWindow::mouseDoubleClickEvent(QMouseEvent* e)
{
     QPoint point = e->pos();
     for(int i=0;i<circuit->gates.length();i++)
     {
         if(point.x() > circuit->gates[i].gate->gate_x && point.x() <circuit->gates[i].gate->gate_x+50&&point.y() > circuit->gates[i].gate->gate_y && point.y() <circuit->gates[i].gate->gate_y+50 &&circuit->gates[i].gate->type==1)
             circuit->gates[i].gate->output=circuit->gates[i].gate->output==1?0:1;
     }
     repaint();
}
void MainWindow::mouseMoveEvent(QMouseEvent *e)
{
     QPoint point = e->pos();
     temppoint_02=e->pos();
     //监测门的移动
     for(int i=0;i<circuit->gates.length();i++)
     {
         if(circuit->gates[i].gate->clickState==2 /*&& point.x() > circuit->gates[i].gate.gate_x && point.x() < circuit->gates[i].gate.gate_x+50&&point.y() > circuit->gates[i].gate.gate_y &&point.y() <circuit->gates[i].gate.gate_y+50*/)
         {
             circuit->gateMove(point.x(),point.y(),i);
             QWidget::repaint();
             break;
         }
     }
}

void MainWindow::mouseReleaseEvent(QMouseEvent *e)
{
    tempLineFlag=0;
   QPoint point = e->pos();
   circuit->selectGate_2(point.x(),point.y());
   ConnectGateAndGate(circuit);
}


void MainWindow::ConnectGateAndGate(CircuitGraph *circuit)
{
    int from,to;
    bool flag_from=false,flag_to=false;
    for(int i=circuit->gates.length()-1;i>=0;i--)//找到from门
    {
        if(circuit->gates[i].gate->clickState==1)
        {
           from=i;
           flag_from=true;
           break;
        }
    }
    for(int i=circuit->gates.length()-1;i>=0;i--)//找到to门
    {
        if(circuit->gates[i].gate->clickState==3)
        {
            to=i;
            flag_to=true;
            break;
        }
    }
    if(flag_from&&flag_to)
    {
        circuit->setEdge(from,to);
    }
    for(int i=circuit->gates.length()-1;i>=0;i--)//状态清零
    {
        if(circuit->gates[i].gate->clickState==1 || circuit->gates[i].gate->clickState==3)
        {
           circuit->gates[i].gate->clickState=0;
        }
    }
}
MainWindow::~MainWindow()
{
    delete ui;
}


